﻿' ******************************************************************************
' ** 
' **  Yahoo! Managed
' **  Written by Marius Häusler 2011
' **  It would be pleasant, if you contact me when you are using this code.
' **  Contact: YahooFinanceManaged@gmail.com
' **  Project Home: http://code.google.com/p/yahoo-finance-managed/
' **  
' ******************************************************************************
' **  
' **  Copyright 2011 Marius Häusler
' **  
' **  Licensed under the Apache License, Version 2.0 (the "License");
' **  you may not use this file except in compliance with the License.
' **  You may obtain a copy of the License at
' **  
' **    http://www.apache.org/licenses/LICENSE-2.0
' **  
' **  Unless required by applicable law or agreed to in writing, software
' **  distributed under the License is distributed on an "AS IS" BASIS,
' **  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
' **  See the License for the specific language governing permissions and
' **  limitations under the License.
' ** 
' ******************************************************************************


Namespace Base

    ''' <summary>
    ''' Provides methods for checking the online status and ping info.
    ''' </summary>
    ''' <remarks></remarks>
    Public Class OnlineCheck
        Inherits StringDownload
        ''' <summary>
        ''' Raises if an asynchronous online check completes.
        ''' </summary>
        ''' <param name="sender">The event raising object.</param>
        ''' <param name="e">The results of the asynchronous online check.</param>
        ''' <remarks></remarks>
        Public Event AsyncDownloadCompleted(ByVal sender As OnlineCheck, ByVal e As OnlineCheckCompletedEventArgs)

        Private mURL As String = String.Empty

        ''' <summary>
        ''' Gets or sets the URL that will be used for proving.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property URL() As String
            Get
                Return mURL
            End Get
            Set(ByVal value As String)
                mURL = value
            End Set
        End Property

        ''' <summary>
        ''' Checks the specific URL for online availability.
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function Download() As OnlineCheckResponse
            Return Me.ToResponse(MyBase.DownloadString(mURL))
        End Function
        ''' <summary>
        ''' Checks asynchronously the specific URL for online availability.
        ''' </summary>
        ''' <remarks>There is only one async check possible at one time. If a check start when another is running, the old one will be canceled.</remarks>
        Public Overloads Sub DownloadAsync(Optional ByVal userArgs As Object = Nothing)
            Me.CancelAsyncAll()
            MyBase.DownloadStreamAsync(mURL, userArgs)
        End Sub

        ''' <summary>
        ''' Sets the URL http://ipinfo.info/ipn/ for checking.
        ''' </summary>
        ''' <remarks>With this URL you're able to get the requesting machine's IP and provider.</remarks>
        Public Sub SetDefaultUrl()
            mURL = "http://ipinfo.info/ipn/"
        End Sub

        ''' <summary>
        ''' Default constructor
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
            Me.SetDefaultUrl()
        End Sub

        Private Sub DownloadAsync_Completed(ByVal sender As Download, ByVal e As StringDownloadCompletedEventArgs) Handles MyBase.AsyncStringDownloadCompleted
            RaiseEvent AsyncDownloadCompleted(Me, New OnlineCheckCompletedEventArgs(e.UserArgs, Me.ToResponse(e.Response)))
        End Sub

        Private Function ToResponse(ByVal resp As StringResponse) As OnlineCheckResponse
            Dim ip As IPAddress = Nothing
            Dim provider As String = String.Empty
            If resp.Connection.State = ConnectionState.Success Then
                Dim match As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(resp.Result, "<h4>.*?<br>.*?</h4>")
                If match.Success Then
                    Dim val As String = match.Value.Replace("<h4>", "").Replace("</h4>", "")
                    Dim index As Integer = val.IndexOf("<br>")
                    Try
                        ip = System.Net.IPAddress.Parse(val.Substring(0, index))
                        If index > -1 Then
                            provider = val.Substring(index + 4)
                        End If
                    Catch ex As Exception
                    End Try
                End If
            End If
            Return New OnlineCheckResponse(resp.Connection, ip, provider)
        End Function

    End Class

    ''' <summary>
    ''' Provides information and response of an asynchronous online check.
    ''' </summary>
    ''' <remarks></remarks>
    Public Class OnlineCheckCompletedEventArgs
        Inherits Base.DownloadCompletedEventArgs
        ''' <summary>
        ''' Gets the response with connection information.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overloads ReadOnly Property Response() As OnlineCheckResponse
            Get
                Return DirectCast(MyBase.Response, OnlineCheckResponse)
            End Get
        End Property
        Friend Sub New(ByVal userArgs As Object, ByVal resp As OnlineCheckResponse)
            MyBase.New(userArgs, resp)
        End Sub
    End Class

    ''' <summary>
    ''' Provides online status and downloaded ping information.
    ''' </summary>
    ''' <remarks></remarks>
    Public Class OnlineCheckResponse
        Inherits Base.Response
        Private mIP As IPAddress
        Private mProvider As String
        ''' <summary>
        ''' The IP of the requesting machine.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>Only possible with default URL.</remarks>
        Public ReadOnly Property IP() As IPAddress
            Get
                Return mIP
            End Get
        End Property
        ''' <summary>
        ''' The provider of the IP.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>Only possible with default URL.</remarks>
        Public ReadOnly Property Provider() As String
            Get
                Return mProvider
            End Get
        End Property
        ''' <summary>
        ''' Returns a value that indicates the success of the connection.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>Indicates Connection.State has value "Success".</remarks>
        Public Overloads ReadOnly Property Result() As Boolean
            Get
                Return CBool(MyBase.Result)
            End Get
        End Property
        Friend Sub New(ByVal info As Base.ConnectionInfo, ByVal ip As IPAddress, ByVal prov As String)
            MyBase.New(info, info.State = ConnectionState.Success)
            mIP = ip
            mProvider = prov
        End Sub
    End Class

End Namespace
